package model.MatriceCreuseOBSOLETE;

import java.awt.Point;
import java.util.LinkedList;

import model.PointControl;

public class MatriceCreuse {
	private Line lastLine = null;

	public boolean isOverPoint(Point a) {
		// FIXME : vérifier si le clic est dans le carré et non strictement sur
		// le point.
		if (lastLine == null)
			return false;
		// recherche ligne précédente
		Line previousLine = findLineOrPreviousOrNextLine(lastLine, a.getY());

		if (previousLine.getY() != a.getY())
			return false;

		// recherche colonne précédente
		PointControl previousColumn = findColumnOrPreviousOrNextColumn(previousLine
				.getPointCourant().getThisPoint(), a.getX());
		if (previousColumn.getX() != a.getX())
			return false;

		return true;
	}

	public void remove(Point origine) {
		PointControl newPointControl = new PointControl(origine);

		// cas liste vide
		if (lastLine == null) {
			throw new RuntimeException(
					"Suppression d'un point alors que la liste est vide.");
		}
		lastLine = lastLine.getThisLine(); // si on l'a supprimé.
		// cas liste vide
		if (lastLine == null) {
			throw new RuntimeException(
					"Suppression d'un point alors que la liste est vide.");
		}

		// recherche ligne précédente
		Line previousLine = findLineOrPreviousOrNextLine(lastLine, origine.getY());

		// ajout du point àl'interieur de la ligne
		if (origine.getY() != previousLine.getY()) {
			// on n'a pas trouvé la ligne
			throw new RuntimeException(
					"Suppression d'un point alors que la liste est vide.");
		} else {
			newPointControl.setLigne(previousLine);
			// on a trouvé la ligne exacte
			PointControl previousColumn = findColumnOrPreviousOrNextColumn(
					previousLine.getPointCourant().getThisPoint(), origine
							.getX());

			if (origine.getX() != previousColumn.getX()) {
				throw new RuntimeException(
						"Suppression d'un point alors que la liste est vide.");
			} else {
				// newPointControl.
				newPointControl.removeMe();
			}
		}
	}

	public void add(Point addedPoint) {
		PointControl newPointControl = new PointControl(addedPoint);
		// cas liste vide
		if (lastLine == null) {
			Line newLine = new Line(addedPoint.getY(), newPointControl);
			lastLine = newLine;
			newPointControl.setLigne(newLine);
			return;
		}

		// recherche ligne précédente
		Line previousLine = findLineOrPreviousOrNextLine(lastLine, addedPoint
				.getY());

		// ajout du point àl'interieur de la ligne
		if (addedPoint.getY() < previousLine.getY()) {
			// on n'a pas trouvé la ligne
			Line nouvelleLigne = new Line(newPointControl.getY(),
					newPointControl);
			previousLine.insertLine(nouvelleLigne);
			newPointControl.setLigne(nouvelleLigne);
		} else if (addedPoint.getY() > previousLine.getY()) {
			Line nouvelleLigne = new Line(newPointControl.getY(),
					newPointControl);
			previousLine.insertLineBefore(nouvelleLigne);
			newPointControl.setLigne(nouvelleLigne);
		} else {
			// on a trouvé la ligne exacte
			PointControl previousColumn = findColumnOrPreviousOrNextColumn(
					previousLine.getPointCourant(), addedPoint.getX());

			if (addedPoint.getX() < previousColumn.getX()) {
				previousColumn.insertPoint(newPointControl);
				previousLine.setCurrentPoint(newPointControl);

			} else if (addedPoint.getX() > previousColumn.getX()) {
				previousColumn.insertPointBefore(newPointControl);
				previousLine.setCurrentPoint(newPointControl);
			} else
				throw new RuntimeException("Ajout d'un élément sur un autre"); // FIXME

		}

	}

	private PointControl findColumnOrPreviousOrNextColumn(
			PointControl beginSearch, double searchedColumn) {
		if (beginSearch == null)
			throw new RuntimeException();
		// on est déja après ou
		// on se place après le point en X
		while (searchedColumn < beginSearch.getX()
				&& beginSearch.getNextX() != null)
			beginSearch = beginSearch.getNextX();
		// on se place sur ou juste avant
		while (searchedColumn > beginSearch.getX()
				&& beginSearch.getPreviousX() != null)
			beginSearch = beginSearch.getPreviousX();
		return beginSearch;
	}

	private Line findLineOrPreviousOrNextLine(Line beginSearch,
			double searchedLine) {
		if (beginSearch == null)
			throw new RuntimeException();
		// on bouge pas et on est déja après la ligne ou
		// on se place après le point en Y
		while (searchedLine < beginSearch.getY()
				&& beginSearch.getNext() != null) {
			beginSearch = beginSearch.getNext();
		}
		// on se ramene a l'élément avant ou sur l'élément lui meme.
		while (searchedLine > beginSearch.getY()
				&& beginSearch.getPrevious() != null) {
			beginSearch = beginSearch.getPrevious();
		}
		return beginSearch;
	}

	public void printMySelf() {
		Line beginSearch = lastLine;
		while (beginSearch.getPrevious() != null) {
			beginSearch = beginSearch.getPrevious();
		}
		PointControl beginSearch2 = beginSearch.getPointCourant();
		while (beginSearch2.getPreviousX() != null)
			beginSearch2 = beginSearch2.getPreviousX();
		
		while (beginSearch.getNext() != null) {
			System.out.println("Ligne : "+ beginSearch.getY());
			while (beginSearch2.getNextX() != null) {
				System.out.println("Colonne : "+ beginSearch.getY());

				beginSearch2 = beginSearch2.getNextX();
			}
			beginSearch = beginSearch.getNext();
		}
		
		
	}

}
